package com.lhy.admin.common.mvcplus.service;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhy.admin.common.mvcplus.entity.BasePage;
import com.lhy.admin.common.mvcplus.entity.ReqCriteria;
import com.lhy.admin.common.mvcplus.entity.RespPage;
import com.lhy.admin.common.mvcplus.entity.SearchCriteria;
import com.lhy.admin.common.mvcplus.wrapper.WrapperHelper;
import com.lhy.admin.util.ReflectionUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Optional;

/**
 * 简易增删改查服务，在mybatis-plus service基础上扩展了一些常用方法
 *
 * @param <M>
 * @param <T>
 */
@Slf4j
public abstract class SimpleService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements ExtendService<T> {

    @Override
    public Optional<T> getOne(T bean) {
        return this.list(WrapperHelper.newAndEqQueryWrapper(bean, getEntityClass())).stream().findFirst();
    }


    @Override
    public List<T> list(T bean) {
        return this.list(WrapperHelper.newAndEqQueryWrapper(bean, getEntityClass()));
    }

    @Override
    public boolean remove(T bean) {
        return this.remove(WrapperHelper.newAndEqQueryWrapper(bean, getEntityClass()));
    }

    @Override
    public boolean exist(T bean) {
        return this.baseMapper.exists(WrapperHelper.newAndEqQueryWrapper(bean, getEntityClass()));
    }


    /**
     * toPlusPage
     * <p/>
     * 分页page转为PlusPage
     *
     * @param BasePage
     * @return com.baomidou.mybatisplus.extension.plugins.pagination.Page
     * @throws
     * @date 2021/5/18 17:27
     */
    protected Page<T> toPlusPage(BasePage BasePage) {
        return new Page<>(BasePage.getPage().longValue(), BasePage.getRows().longValue());
    }


    /**
     * toPage
     * <p/>
     * 分页page转为PlusPage
     *
     * @param pageReq
     * @param iPage
     * @return Page
     * @throws
     * @date 2021/5/18 17:27
     */
    protected RespPage<T> toRespPage(BasePage pageReq, IPage<T> iPage) {
        return new RespPage<>(pageReq.getPage(), pageReq.getRows(), (int) iPage.getTotal(), iPage.getRecords());
    }

    @Override
    public boolean save(T entity) {
        return super.save(entity);
    }

    @Override
    public boolean update(T entity, Wrapper<T> updateWrapper) {
        return super.update(entity, updateWrapper);
    }

    @Override
    public boolean updateById(T entity) {
        return super.updateById(entity);
    }


    /**
     * updateSelectiveById
     * <p/>
     * 根据主键更新非空字段
     *
     * @param bean
     * @return boolean
     * @throws
     * @date 2019/3/18 17:27
     */
    @Override
    public boolean updateSelectiveById(T bean) {
        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        WrapperHelper.setWrapperWhere(bean, updateWrapper);
        WrapperHelper.setWrapperSet(bean, updateWrapper);
        return this.update(ReflectionUtils.newInstance(bean.getClass()), updateWrapper);
    }


    /**
     * searchCriteria
     * 通过条件构造器创建 queryWrapper 例如：</br>
     * {
     * "rows": 10,
     * "page": 1,
     * "sc": [
     * {
     * "condition": "and",
     * "comparator": "like right",
     * "field": "name",
     * "value": "hello world"
     * },
     * {
     * "condition": "and",
     * "comparator": "eq",
     * "field": "isDel",
     * "value": 0
     * },
     * {
     * "condition": "by",
     * "comparator": "order by",
     * "field": "id,name",
     * "value": "asc"
     * }
     * ]
     * }
     * } <br>
     * 表示以右侧模糊匹配方式 查询name字段为hello world 开头,并且idDel为 0 的前十条数据，以 id,name 顺序排序
     *
     * @param criteriaReq criteriaReq
     * @return {@link RespPage<T>}
     * @author hyluan
     * @date 2022/6/27 17:56
     */
    public RespPage<T> searchCriteria(ReqCriteria criteriaReq) {
        Class<T> entityClass = getEntityClass();
        QueryWrapper<T> queryWrapper = WrapperHelper.newConditionWrapper(criteriaReq.getSc(), entityClass, criteriaReq.getColumns());
        //page或rows<1时查询全部
        if (criteriaReq.getPage() < BasePage.DEFAULT_PAGE_NUMBER || criteriaReq.getRows() < BasePage.DEFAULT_PAGE_NUMBER) {
            List<T> list = this.list(queryWrapper);
            return new RespPage<>(BasePage.DEFAULT_PAGE_NUMBER, list.size(), list.size(), list);
        }
        Page<T> page = this.page(toPlusPage(criteriaReq), queryWrapper);
        return toRespPage(criteriaReq, page);

    }


    /**
     * countCriteria 条件统计
     *
     * @param searchCriteria searchCriteria
     * @return {@link long}
     * @author hyluan
     * @date 2023/2/15 15:43
     */
    @Override
    public long countCriteria(SearchCriteria searchCriteria) {
        Class<T> entityClass = getEntityClass();
        QueryWrapper<T> queryWrapper = WrapperHelper.newConditionWrapper(searchCriteria, entityClass);
        return this.count(queryWrapper);
    }

    /**
     * deleteCriteria 条件删除
     *
     * @param searchCriteria searchCriteria
     * @return {@link boolean}
     * @author hyluan
     * @date 2023/2/15 15:43
     */
    @Override
    public boolean deleteCriteria(SearchCriteria searchCriteria) {
        Class<T> entityClass = getEntityClass();
        QueryWrapper<T> queryWrapper = WrapperHelper.newConditionWrapper(searchCriteria, entityClass);
        return this.remove(queryWrapper);
    }


}
